﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LINQ_Exercises
{
    class Program
    {
        static IEnumerable<object> ExtractStudentsOrderedByFirstNameByGroupWithLINQ(
            int group, List<Student> listOfStudents)
        {
            var query =
                from student in listOfStudents
                where student.GroupNumber == 2
                orderby student.FirstName
                select student;

            return query;
        }

        static IEnumerable<object> ExtractStudentsOrderedByFirstNameByGroupWithExtensionMethods(
            int group, List<Student> listOfStudents)
        {
            var query = listOfStudents.Where(student => student.GroupNumber == 2).OrderBy(student => student.FirstName);
            return query;
        }

        static IEnumerable<object> ExtractStudentsByEmailDomains(
            string emailDomain, List<Student> listOfStudents)
        {
            var query =
                from student in listOfStudents
                where student.Email.EndsWith(emailDomain)
                select student;

            return query;
        }

        static IEnumerable<object> ExtractStudentsWithAtLeastOneMark6(List<Student> listOfStudents)
        {
            var query =
                from student in listOfStudents
                where student.Marks.Contains(6)
                select new
                {
                    FullName = student.FirstName + " " + student.LastName,
                    Marks = student.Marks
                };

            return query;
        }

        static IEnumerable<object> ExtractStudentsWithExactlyTwoMarks2(List<Student> listOfStudents)
        {
            return listOfStudents.Where(student => student.Marks.FindAll(mark => mark.Equals(2)).Count == 2).Select(
                student => new { FullName = student.FirstName + " " + student.LastName, Marks = student.Marks });
        }

        static IEnumerable<object> ExtractStudentsFromSpecificDepartment(
            List<Student> listOfStudents, List<Group> listOfGroups, string department)
        {
            var query =
                from student in listOfStudents
                join groups in listOfGroups on student.GroupNumber equals groups.GroupNumber
                where groups.DepartmentName == department
                select student;

            return query;
        }

        static IEnumerable<string> GetLongestStringFromStringArray(string[] array)
        {
            var query =
                from a in array
                where a.Length == array.Max(x => x.Length)
                select a;

            return query;
        }

        static IEnumerable<IGrouping<object, object>> ExtractStudentsGroupedByGroupNameWithLINQ(
            List<Student> listOfStudents, List<Group> listOfGroups)
        {
            var query =
                from student in listOfStudents
                join groups in listOfGroups on student.GroupNumber equals groups.GroupNumber
                group student by groups.DepartmentName;

            return query;
        }

        static IEnumerable<object> ExtractStudentsGroupedByGroupNameWithExtensionMethods(
            List<Student> listOfStudents, List<Group> listOfGroups)
        {
            var query = listOfGroups.GroupJoin(listOfStudents, group => group.GroupNumber, student => student.GroupNumber,
                (group, students) => new { DepartmentName = group.DepartmentName, StudentCollection = students });

            return query;
        }

        static T Cast<T>(object obj, T Type)
        {
            return (T)obj;
        }

        static void Main()
        {
            List<Student> listOfStudents = new List<Student>();
            listOfStudents.Add(new Student("Nonka", "Noncheto", "80698", "+3590887769856", "hello@gyuvetch.bg",
                new List<int>() { 2, 3, 5, 4 }, 2));
            listOfStudents.Add(new Student("Rumen", "Paletov", "99639", "+359066987654", "hello_world@abv.bg",
                new List<int>() { 6, 2, 6, 2, 6 }, 2));
            listOfStudents.Add(new Student("Nikolas", "Koliokikus", "98763", "+359632145879", "olimpicus@live.com",
                new List<int>() { 6, 6, 6 }, 2));
            listOfStudents.Add(new Student("Gradivacus", "Stratuvakius", "20365", "+359789456123", "cocounutos@abv.bg",
                new List<int>() { 6, 4, 6 }, 5));

            List<Group> listOfGroups = new List<Group>();
            listOfGroups.Add(new Group(2, "Computer Science"));
            listOfGroups.Add(new Group(5, "Mathematics"));

            string[] arr = new string[] { "Rumen", "Atanaasov", "Paletov", "Koko", "Pukandrokolis", "Mr.Mr.Mrs.", "Norchetoo" };

            var query = ExtractStudentsGroupedByGroupNameWithExtensionMethods(listOfStudents, listOfGroups);

            foreach (var group in query)
            {
                var g = Cast(group, new { DepartmentName = default(string), StudentCollection = default(IEnumerable<Student>) });
                Console.WriteLine("{0}:\n", g.DepartmentName);
                foreach (var student in g.StudentCollection)
                {
                    Console.WriteLine(student);
                }
            }
        }
    }
}

